﻿// -------------------------------------------------------------------------
//    @FileName         :    NFMirrorModule.cpp
//    @Author           :    Gao.Yi
//    @Date             :    2025-08-29
//    @Email			:    445267987@qq.com
//    @Module           :    NFMirrorModule
//    @Desc             :
//
// -------------------------------------------------------------------------

#include "NFMirrorModule.h"

#include "NFLoginUtil.h"
#include "NFMirrorService.h"
#include "NFMirrorSessionMgr.h"
#include "NFPacketSendUtil.h"
#include "proto_cs_cmd.nanopb.h"
#include "proto_svr_common.nanopb.h"
#include "proto_svr_onlinesvr.pb.h"
#include "NFLogicServer/NFLogicServerPlayerPlugin/Session/NFSession.h"
#include "NFLogicServer/NFLogicServerPlayerPlugin/Session/NFSessionUtil.h"
#include "NFServerComm/NFServerCommon/NFIServerMessageModule.h"

NFMirrorModule::NFMirrorModule(NFIPluginManager* p):NFLogicDynamicModule(p)
{

}

NFMirrorModule::~NFMirrorModule()
{
}

int NFMirrorModule::Awake()
{
    RegisterServerMessage(NF_ST_LOGIC_SERVER, E_SS_ZONE_ROLE_MIRROR_SESSION);
    RegisterServerMessage(NF_ST_LOGIC_SERVER, E_SS_ZONE_ROLE_MIRROR_LOGIN);
    RegisterServerMessage(NF_ST_LOGIC_SERVER, E_SS_ZONE_TRANSFER_MIRROR_SESSION);

    return 0;
}

int NFMirrorModule::OnHandleServerMessage(uint32_t msgId, NFDataPackage& packet, uint64_t param1, uint64_t param2)
{
    if (!m_pObjPluginManager->IsInited(NF_ST_LOGIC_SERVER))
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "Logic Server not inited, drop client msg:{}", packet.ToString());
        return -1;
    }

    if (m_pObjPluginManager->IsServerStopping())
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "Logic Server is Stopping, drop client msg:{}", packet.ToString());
        return proto_ff::ERR_CODE_SERVER_IS_STOPPING;
    }

    int iRetCode = 0;
    switch (packet.nMsgId)
    {
        case E_SS_ZONE_ROLE_MIRROR_SESSION:
        {
            iRetCode = OnHandleRoleMirrorSession(msgId, packet, param1, param2);
            break;
        }
        case E_SS_ZONE_ROLE_MIRROR_LOGIN:
        {
            iRetCode = OnHandleRoleMirrorLogin(msgId, packet, param1, param2);
            break;
        }
        case E_SS_ZONE_TRANSFER_MIRROR_SESSION:
        {
            iRetCode = OnHandleTransferMirrorSession(msgId, packet, param1, param2);
            break;
        }
        default:
            NFLogError(NF_LOG_DEFAULT, 0, "not handle msg:{}", packet.nMsgId);
    }

    return iRetCode;
}

int NFMirrorModule::OnHandleRoleMirrorSession(uint32_t msgId, NFDataPackage& packet, uint64_t param1, uint64_t param2)
{
    proto_ff::Proto_SSZoneMirrorSessionReq req;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, req);

    uint64_t roleId = req.role_id();
    LOG_INFO(roleId, "roleId:{} mirror session req from {}", roleId, NFServerIDUtil::GetBusNameFromBusID(packet.nSrcId));

    int iRetCode = 0;
    NFSession* pSession = nullptr;
    do
    {
        int lockedSessionId = NFMirrorSessionMgr::Instance()->GetLockedLoginMirrorSessionId(roleId);
        if (lockedSessionId != 0)
        {
            iRetCode = ERR_CODE_ROLE_LOGIN_MIRROR_SESSION_EXIST;
            LOG_WARN(roleId, iRetCode, "roleId:{} mirror session exist lockedSessionId:{} req from {}", roleId, lockedSessionId, NFServerIDUtil::GetBusNameFromBusID(packet.nSrcId));
            break;
        }

        pSession = NFSession::CreateObj();
        if (pSession == nullptr)
        {
            iRetCode = -1;
            LOG_ERR(roleId, iRetCode, "NFSession::CreateObj failed");
            break;
        }

        pSession->Connect(&req.conn_info());
        pSession->Login(&req.client_info(), req.login_pri(), req.login_zone_id());

        iRetCode = NFMirrorSessionMgr::Instance()->LockLoginMirror(roleId, pSession->GetGlobalId());
        if (iRetCode != 0)
        {
            LOG_ERR(roleId, iRetCode, "LockLoginMirror failed, roleId:{} req from {}", roleId, NFServerIDUtil::GetBusNameFromBusID(packet.nSrcId));
            break;
        }

        LOG_INFO(roleId, "roleId:{} mirror session success, req from {}", roleId, NFServerIDUtil::GetBusNameFromBusID(packet.nSrcId));
    }
    while (false);

    int sessionId = (pSession == nullptr) ? 0 : pSession->GetGlobalId();

    proto_ff::Proto_SSZoneMirrorSessionRsp rsp;
    if (iRetCode != 0)
    {
        if (pSession)
        {
            NFSession::DestroyObj(pSession);
        }
    }
    rsp.set_session_id(sessionId);

    FindModule<NFIServerMessageModule>()->SendTransToLogicServer(NF_ST_LOGIC_SERVER, packet.nSrcId, E_SS_ZONE_ROLE_MIRROR_SESSION, rsp, roleId, 0, param1);

    return 0;
}

int NFMirrorModule::OnHandleRoleMirrorLogin(uint32_t msgId, NFDataPackage& packet, uint64_t param1, uint64_t param2)
{
    proto_ff::Proto_SSZoneMirrorLogin req;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, req);

    int sessionId = req.session_id();
    uint64_t roleId = req.role_id();

    auto pSession = NFSessionUtil::GetSessionObj(sessionId);
    CHECK_NULL_WF(roleId, pSession, "roleId:{} mirror login session not exist, sessionId:{} from {}", roleId, sessionId, NFServerIDUtil::GetBusNameFromBusID(packet.nSrcId));

    NFLoginUtil::ServerLoginRole(pSession, roleId);
    return 0;
}

int NFMirrorModule::OnHandleTransferMirrorSession(uint32_t msgId, NFDataPackage& packet, uint64_t param1, uint64_t param2)
{
    proto_ff::Proto_SSZoneTranser2MirrorSession req;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, req);

    int sessionId = req.session_id();
    auto pSession = NFSessionUtil::GetSessionObj(sessionId);
    CHECK_NULL_WF(sessionId, pSession, "transfer mirror session not exist, sessionId:{} from {}", sessionId, NFServerIDUtil::GetBusNameFromBusID(packet.nSrcId));

    NFPacketSendUtil::SendToClient(pSession, req.msg_id(), req.msg_data());
    return 0;
}
